#ifndef AGGREGATOR_H__
#define AGGREGATOR_H__

//include header
#include "Stuff.h"
#include "Iterator.h"
#include <memory>

//using namespace
using namespace std;


namespace npIterator
{
    //class forward declaration

    class Aggregator // : public BaseClass
    {
        //friend
        
        //embedded type
        public: enum class ErrorEnum
            {
                //occupied居然比stuffLen还长
                WierdError = 1,
                IndexOutOfRange = 2
            };
        
        //class skeleton
        public: Aggregator();
        public: virtual ~Aggregator();
        public: Aggregator(const Aggregator& cpy);
        public: Aggregator& operator=(const Aggregator& asn);
        public: Aggregator(Aggregator&& mov) noexcept;
        public: Aggregator& operator=(Aggregator&& mva) noexcept;
        public: virtual Aggregator* clone() const;
        public: virtual Aggregator* steal(void* sft = nullptr);

        //other constructors
        
        //public methods
        public: void push(const Stuff& stuff) throw(ErrorEnum);
        public: void pop(size_t indx) throw();
        public: Stuff& getByIndex(size_t indx) const throw(ErrorEnum);
        public: size_t count() const throw();
        public: weak_ptr<Iterator> createIterator(weak_ptr<Aggregator> aggregator) throw();
        
        //protected methods
        
        //private methods
        
        //protected data
        //类中不应该存在protected 访问级别的data
        //要么私有，要么私有而后给出protected 访问级别的methods
        //!!!
        
        //private data
        //类中不应存在指针类型成员，
        //取而代之，应使用智能指针予以包裹
        //使用unique_ptr表示类独占指针指向对象
        //使用shared_ptr表示类拥有指针指向对象
        //使用weak_ptr表示类仅可以使用指针指向对象
        //智能指针对指针成员的封装准则：
        //1.如果业务逻辑给出的是独占，则务必使用unique_ptr
        //2.推敲业务逻辑，如果是共享的(share_ptr)，则尽可能少的共享指针对象
        //3.如果从业务逻辑中发现类仅仅使用某个指针所指对象，则务必使用weak_ptr包裹指针，
        //  以此切实地描述这种使用而不拥有的关系
        private: size_t occupied;
        private: size_t stuffLen;
        private: unique_ptr<Stuff[]>  stuffs;
        private: shared_ptr<Iterator> iter;
        
        //static part
        private: static int initCapacity;
        private: static float increaseFactor;
        
        //others
    };

    //inline functions
    inline size_t Aggregator::count() const throw()
    {
        return this->occupied;
    }

    inline weak_ptr<Iterator> Aggregator::createIterator(weak_ptr<Aggregator> aggregator) throw()
    {
        if (!this->iter)
        {
            this->iter = make_shared<Iterator>(aggregator);
        }
        return weak_ptr<Iterator>(this->iter);
    }
} // namespace npIterator


#endif //AGGREGATOR_H__
